<?php

namespace app\api\model\project;

use app\api\model\project\ProjectOrder as ProjectOrderModel;
use app\api\model\User;
use think\Db;
use think\Model;


class ProjectOrderUnion extends Model
{





    // 表名
    protected $name = 'project_order_union';

    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'integer';

    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = false;

    // 追加属性
    protected $append = [

    ];

    //判断下单日期是否与已接单时间段冲突
    public function judgeDate($staff_id,$user_start_date,$user_start_time,$user_end_date,$user_end_time,$name,$apply_id)
    {
        $apply_info = ProjectApply::get($apply_id);

        $apply_week = explode(',',$apply_info->work_day);

        //判断是不是非接单日期
        $day_list = Dates1($user_start_date,$user_end_date);
        foreach ($day_list as $k=>$v){
            $week = date('N',strtotime($v));
            if (!in_array($week,$apply_week)){
                throw new \Exception($name.'项目日期包含非接单日期！');
            }
        }

        //判断是不是休息时间
        if ($user_start_time<$apply_info->service_start_time||$user_end_time>$apply_info->service_end_time){
            throw new \Exception($name.'项目日期时间含有休息时间！');
        }

        $order_list = collection(ProjectOrderModel::where(['staff_id'=>$staff_id])
            ->where('service_start_date','>',date('Y-m-d'))
            ->field('service_start_date,service_end_date,service_start_time,service_end_time')
            ->select())->toArray();

        $time_list = collection(ProjectStaffTime::where(['staff_id'=>$staff_id])
            ->where('service_start_date','>',date('Y-m-d'))
            ->field('service_start_date,service_end_date,service_start_time,service_end_time')
            ->select())->toArray();

        $existing_intervals = array_merge($order_list,$time_list);
        //dump($existing_intervals);die;
        // 用户选择的时间段
        $user_start = \DateTime::createFromFormat('Y-m-d H:i', $user_start_date . ' ' . $user_start_time);
        $user_end = \DateTime::createFromFormat('Y-m-d H:i', $user_end_date . ' ' . $user_end_time);

        // 确保时区一致
        $user_start->setTimezone(new \DateTimeZone('UTC'));
        $user_end->setTimezone(new \DateTimeZone('UTC'));

        foreach ($existing_intervals as $interval) {
            if ($this->isConflict($user_start, $user_end, $interval)) {
                throw new \Exception($name.'项目时间冲突！');
            }
        }
    }

    public function isConflict($user_start, $user_end, $interval) {
        // 将时间段的开始和结束时间转换为DateTime对象
        $existing_start = \DateTime::createFromFormat('Y-m-d H:i', $interval['service_start_date'] . ' ' . $interval['service_start_time']);
        $existing_end = \DateTime::createFromFormat('Y-m-d H:i', $interval['service_end_date'] . ' ' . $interval['service_end_time']);

        // 设置时区
        $existing_start->setTimezone(new \DateTimeZone('UTC'));
        $existing_end->setTimezone(new \DateTimeZone('UTC'));

        // 判断是否有重叠
        return !($user_end < $existing_start || $user_start > $existing_end);
    }



    public function add($params)
    {
        $staff_id = $params['staff_id'];
        $user_id = $params['user_id'];
        $name = $params['name'];
        $mobile = $params['mobile'];
        $remark = $params['remark'];

        $staff_info = ProjectStaff::get($staff_id);
        $user_info = User::get($user_id);
        if ($user_info['level']==0){
            throw new \Exception('普通用户不能报名');
        }
        if ($staff_info['user_level']!='0'){
            $user_level_arr = explode(',',$staff_info['user_level']);
            if (!in_array($user_info['level'],$user_level_arr)){
                throw new \Exception('不满足该服务人员的服务对象要求');
            }
        }

        $model = new ProjectOrderUnion();
        $pay_price = 0;
        $project_arr = json_decode($params['project_arr'],true)?json_decode($params['project_arr'],true):_json_decode($params['project_arr']);

        $apply_id = array_column($project_arr,'id');

        foreach ($project_arr as $k=>$v){
            $pay_price+=$v['price']*$v['num'];
            //判断下单日期是否含有不接单日期
            //$week = date('N',strtotime($v['service_start_date']));
            //判断日期冲突
            $this->judgeDate($staff_id,$v['service_start_date'],$v['service_start_time'],$v['service_end_date'],
                $v['service_end_time'],$v['name'],$v['id']);
        }
        //dump($apply_id);die;
        if (empty($name)){
            throw new \Exception('请输入联系人');
        }
        if (empty($mobile)){
            throw new \Exception('请输入联系电话');
        }

        Db::startTrans();
        try {

            $data = [
                'user_id'=>$user_id,
                'staff_id'=>$staff_id,
                'order_no'=>$this->order_no(),
                'pay_price'=>$pay_price,
                'apply_id'=>implode(',',$apply_id),
                'name'=>$name,
                'mobile'=>$mobile,
                'remark'=>$remark,
            ];

            $res = $model->save($data);
            if ($res){
                $order_model = new ProjectOrder();
                $order_model->add($user_id,$staff_id,$project_arr,$name,$mobile,$remark,$data['order_no']);
                /*foreach ($project_arr as $k=>$v){
                    $order_model->add($user_id,$staff_id,$v['id'],$name,$mobile,$remark,$v['service_start_date'],
                        $v['service_end_date'],$v['service_start_time'],$v['service_end_time']);
                }*/
            }

            Db::commit();
            return $model;
        }catch (\Exception $e) {
            // 回滚事务
            Db::rollback();
            throw new \Exception($e->getMessage().'-'.$e->getLine());
        }
    }

    public function notify($out_trade_no,$paytype)
    {
        $order = ProjectOrderUnion::get(['order_no'=>$out_trade_no]);
        if ($order->pay_status==0){
            $order->pay_type = $paytype;
            $order->pay_status = 1;
            $order->pay_time = time();
            $order->save();
            $order_model = new ProjectOrder();
            $order_model->notifyx($out_trade_no,$paytype);
        }

        return true;
    }


    public function order_no(){
        $order_no = null;
        while (true) {
            $order_no = date('YmdHis') . mt_rand(1000, 9999);
            $exist_order_no = ProjectOrderUnion::get(['order_no' => $order_no]);
            if (!$exist_order_no) {
                break;
            }
        }
        return $order_no;
    }


}
